package pulp;

import StringTools;
import Std;

//i) Serializes variables into html -- how stupid is that?
//	strong - string , em - numbers, u - null and errors
//	<dl><dt><b>age</b></dt><dd><i>23</i></dd></dl> map

//WARNING) <i>, <b> and <ul> work at decoding and encoding , <dl> decoding doesn't yet fully 
//		work in nested arrays and will have to convert to hashlist instead of array .

class Htmlize
{
	var str:String;

	
	public function new(){}


	public static function encode(value : Dynamic)
	{
		if (Std.is(value, String)) 
		{ 
			if (StringTools.startsWith(value, "#err:"))
				return "<u>"+value+"</u>";
			else
				return "<b>"+value+"</b>";
		}
		else if(Std.is(value, Int) || Std.is(value, Float)) 
		{
			return "<i>"+value+"</i>";
		}
		else if(value == null) 
		{
			return '<u>null</u>';  //null and "system messages get underlined (errors)
		}
		else if(Std.is(value, Bool)) 
		{
			return "<i>"+Std.int(value)+"</i>";
		}
		else if (Std.is(value, Array))
		{
			var o:String = '<ul>\n';
			for(key in 0...value.length)
			{
				var value2:String = Htmlize.encode(value[key]);
				o += " <li>"+value2+"</li>\n";
			}
			return o + "</ul>\n";
		}
		else if (Std.is(value, Array))
		//todo for hashtable
		{
			var o:String = '<dl>';
			for(key in 0...value.length)
			{
				var key2:String = Htmlize.encode(key);
				var value2:String = Htmlize.encode(value[key]);
				o += "<dt>"+key2+"</dt><dd>"+value2+"</dd>";
			}
			return o + "</dl>";
		}
		return '';
	}



	public function print_n_decode(str:String)
	{
		trace(str);
		return decode(str);
	}

	public function decode(str_:String):Dynamic
	{
		if (str_ != null) str = StringTools.trim(str_);
	
		//DISCRETE VALUES
		if (StringTools.startsWith(str, "<i>"))
		//numbers
		{
			var strval:String = str.substr(3, str.indexOf('</i>') - 3);
			if (strval.indexOf('.') >= 0)
			{
				var val:Int = Std.parseInt(strval);
				return val;
			}
			else
			{
				var val:Float = Std.parseFloat(strval);
				return val;
			}
		}
		else if (StringTools.startsWith(str, "<b>"))
		//strings
		{
			var val:String = str.substr(3, str.indexOf('</b>') - 3);
			return val;
		}
		//COMPOSITE VALUE uses recursion to parse itself
		else if (StringTools.startsWith(str, '<ul>'))
		{
			//trace(str);
			var arr:Array<Dynamic> = new Array();
			do 
			{
				str = str.substr(str.indexOf('<li>'));
				var val:Dynamic = decode(null);
				arr.push(val);
				str = str.substr(str.indexOf('</li>') + 5);
				str = StringTools.trim(str);
			} while (StringTools.startsWith(str, '<li>'));
			return arr;
		}
		else if (StringTools.startsWith(str, '<dl>'))
		{
			var arr:Array<Dynamic> = new Array();
			do 
			{
				str = str.substr(str.indexOf('<dt>'));
				var key:Dynamic = decode(str);
				str = str.substr(str.indexOf('<dd>'));
				var val:Dynamic = decode(str);
				arr[key] = val;
				str = str.substr(str.indexOf('</dd>') + 5);
				str = StringTools.trim(str);
			} while (StringTools.startsWith(str, '<dt>'));
			return arr;
		}
		else if (StringTools.startsWith(str, '<li>'))
		{
			str = str.substr(4);
			return decode(null);
		}		
		else if (StringTools.startsWith(str, '<dt>'))
		{
			str = str.substr(4);
			return decode(str);
		}
		else if (StringTools.startsWith(str, '<dd>'))
		{
			str = str.substr(4);
			return decode(str);
		}
		return null;
	}	


}